/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2002, GeoVISTA Center
 * Licensed under Simplified BSD License
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
*
* A Panel display a set of color swatches (JLabel). The swatch's size is NOT fixed, does change along with the change to the size of their container panel
  Note:
    - recommend the container using BorderLayout()
    -  This version use JLabel as swatches, hence the Panel WON"T get AWT events (e.g.: MouseEvent)


* @Original Author: jin Chen
* @date: Jan 4, 2005$
* @version: 1.0
*/
package edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.v2;

import edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.DynamicSwatchPane;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;

public class DynamicSwatchPaneImpl extends JPanel implements  DynamicSwatchPane {

    protected int rowCount;
    protected int columnCount;
    protected Dimension gap=new Dimension(-1,-1);//gap between any 2 swatches
    protected JPanel mainP;
    //protected MouseInputAdapter swatchListener=new SwatchPanel.MyMouseAdapter();
    protected java.util.List swatches=new ArrayList();

    /**
     * Determine how swatches layout: usally GridLayout layout compoenents from top ( 1st row) to bottom. This is the case LAYOUT_TOP_BOTTOM
     * But a Legend usually need to layout from bottom ( represent lower y value) to top. So by setting layouttype=LAYOUT_BOTTOM_TOP,
     * legendControl's color scheme will = interactiveLegend's color scheme
     */
    private int layouttype=LAYOUT_BOTTOM_TOP;//LAYOUT_TOP_BOTTOM;//LAYOUT_BOTTOM_TOP;
    private int orientation=SwingConstants.HORIZONTAL; //when display 1-dimension color, it determine how the colors layout. By default, it is HORIZONTAL

    public DynamicSwatchPaneImpl(Color[][] colors) {
        this.initComponents();
        setColors(colors);
    }

    public DynamicSwatchPaneImpl(Color[] colors,int orientation) {
        this.orientation = orientation;
        this.initComponents();
        this.setColors(colors);
    }


    public void setColors(Color[][] colors){
        this.rowCount = colors.length ;
        this.columnCount = colors[0].length ;
        initSwatches(colors);
    }

    public void setColors(Color[] colors){

        if (this.getOrientation() ==SwingConstants.HORIZONTAL) {
            this.rowCount = 1 ;
            this.columnCount = colors.length ;
        } else { //SwingConstants.VERTICAL
            this.rowCount =colors.length  ;
            this.columnCount = 1 ;
        }
        initSwatches(colors);
    }


    public void setGap(int hgap,int vgap) {
        this.gap.setSize(hgap,vgap);
        LayoutManager ly = this.mainP.getLayout();
        if(ly instanceof GridLayout){
        GridLayout layout = (GridLayout) ly;

        layout.setHgap(gap.width );
        layout.setVgap(gap.height );

        }
        mainP.revalidate();
        mainP.repaint();
    }
    public void setSwatchBorderColor(Color c){
        for (Iterator iterator = swatches.iterator(); iterator.hasNext();) {
            JLabel label = (JLabel) iterator.next();
            label.setBorder(new javax.swing.border.LineBorder(c));//);

        }
        this.mainP.repaint();
    }

    public void selectSwatch(edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.v1.DynamicSwatchPaneImpl.Swatch swatch) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void tryAddSelection(edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.v1.DynamicSwatchPaneImpl.Swatch swatch) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void deselectSwatch(edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.v1.DynamicSwatchPaneImpl.Swatch swatch) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void tryAddSelection(Set<edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.v1.DynamicSwatchPaneImpl.Swatch> swatches) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void clearSelection() {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public Set<edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.v1.DynamicSwatchPaneImpl.Swatch> getSelectedSwatches() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public java.util.List getSwatches() {
        return swatches;
    }

    public int getOrientation() {
        return orientation;
    }
    /**
     *
     * @param orientation  only accept 2 values: SwingConstants.HORIZONTAL or //SwingConstants.VERTICAL
     */
    public void setOrientation(int orientation) {
        this.orientation = orientation;
    }

    public int getRowCount() {
        return rowCount;
    }

    public int getColumnCount() {
        return columnCount;
    }

    /*******************************************************************************************************
     *                init
     *******************************************************************************************************/
    protected void initSwatches(Color[]colors){
        Color[][] tmp=convertColors(colors);
        this.initSwatches(tmp);

    }
    protected  Color[][] convertColors(Color[] colors){
        Color[][] tmp=null;
        if(this.getOrientation() ==SwingConstants.HORIZONTAL ){
            tmp=new Color[1][colors.length ];
        for (int i=0;i<colors.length ;i++){
            tmp[0][i]=colors[i];
        }
        }
        else{
              tmp=new Color[colors.length][1 ];
                for (int i=0;i<colors.length ;i++){
                    tmp[i][0]=colors[i];
                }
        }
        return tmp;
    }
    /*protected void init(Color[][] colors){
        //init GUI
        initComponents();


        //set  gap   as default
        initSwatches(colors);


    }*/

    private void initSwatches(Color[][] colors) {
        this.swatches.clear();
        if(gap.width<0)
            gap.width =GAP_WIDTH;
        if(gap.height<0)
            gap.height =GAP_HEIGHT;

        if(colors==null) {
            colors=new Color[rowCount][columnCount];
            for (int i=0;i< rowCount;i++){
                for (int j=0;j< columnCount;j++){
                    colors[i][j]=COLOR_DEFAULT;
                }
            }
        }


        this.mainP.removeAll();
        GridLayout layout = new GridLayout(rowCount, columnCount, gap.width, gap.height);
        mainP.setLayout(layout);
        if(this.layouttype==LAYOUT_BOTTOM_TOP){
            for (int i= rowCount -1;i>=0;i--){
                for (int j=0;j< columnCount;j++){
                    JLabel swatch = createSwatch(colors[i][j]);
                    this.swatches.add(swatch);
                    mainP.add(swatch);
                }
            }
        }
        else{
            for (int i=0;i< rowCount;i++){
                for (int j=0;j< columnCount;j++){
                    JLabel swatch = createSwatch(colors[i][j]);
                    this.swatches.add(swatch);
                    mainP.add(swatch);
                }
            }
        }

         //for loop
        mainP.revalidate();
        this.revalidate();
        this.repaint();
    }

    private void initComponents() {
        if ( mainP==null)
          mainP=new JPanel();
        this.setLayout(new BorderLayout() );
        // this.add()
        this.add(mainP);
    }

    /*private void resetSwatch(Color[][] colors){
        this.mainP.removeAll();
        mainP.setLayout(new java.awt.GridLayout(numOfRow, numOfCulumn, gap.width, gap.height));
        for (int i=0;i<numOfRow;i++){
            for (int j=0;j<numOfCulumn;j++){
                JLabel swatch = createSwatch(colors[i][j]);
                this.swatches.add(swatch);
                mainP.add(swatch);
             }
        } //for loop
        this.revalidate();
        this.repaint();
    }*/
    private JLabel createSwatch(Color color) {
        JLabel swatch = new FixedSwatchPaneImpl.ColorLabel();
        //swatch.setPreferredSize(new Dimension(swatchSize.width , swatchSize.height ));
        swatch.setBorder(new javax.swing.border.LineBorder(Color.white ));
        swatch.setBackground(color);
        swatch.setOpaque(true);
        swatch.setToolTipText("RGB:"+color.getRed() +","+color.getGreen() +","+color.getBlue() );
        return swatch;
    }



    private static DynamicSwatchPaneImpl test2DColors(){

        Color[][] mycolors= create2DSampleColors();
        DynamicSwatchPaneImpl sp=new DynamicSwatchPaneImpl(mycolors);
        sp.setGap(0,0);
        sp.setSwatchBorderColor(Color.white );
        return sp;
    }
    private static DynamicSwatchPaneImpl test1DVerticalColors(){
       /* Color[] mycolors= create1DSampleColors();
        DynamicSwatchPaneImpl sp=new DynamicSwatchPaneImpl(mycolors,SwingConstants.VERTICAL ); */
        Color[][] mycolors= create2DSampleColors();
        DynamicSwatchPaneImpl sp=new DynamicSwatchPaneImpl(mycolors)  ;
        sp.setGap(0,0);
        sp.setSwatchBorderColor(Color.white );
        return sp;
    }
    public  static Color[][] create2DSampleColors() {
        int[][] colorValues=new int[][]{
            {255, 255, 255, // first row.
             192, 192, 192,
             255, 0, 0,
             255, 255, 0,
             0, 255, 0,
             0, 255, 255,
             0, 0, 255,
             255, 0, 255},
            {0, 0, 0,  // second row.
             128, 128, 128,
             128, 0, 0,
             128, 128, 0,
             0, 128, 0,
             0, 128, 128,
             0, 0, 128,
             128, 0, 128,},
            {255, 199, 199,  // 3rd row.
             83, 109, 165,
             204,  255,204,
             153, 153, 204,
             204, 204, 214,
             0, 180, 110,
             252, 253, 205,
             212, 133, 213}
        };
        Color[][] mycolors= FixedSwatchPaneImpl.convert2RowBased(colorValues);
        return mycolors;
    }

    public  static Color[] create1DSampleColors() {
        Color[] colors=new Color[]{
             new Color(255, 255, 255), // first row.
             new Color(192, 192, 192),
             new Color(255, 0, 0),
             new Color(255, 255, 0),
             new Color(0, 255, 0),
             new Color(0, 255, 255),
             new Color(0, 0, 255),
             new Color(255, 0, 255)};
           return colors;
    }




}
